const isDOM = ( typeof HTMLElement === 'object' ) ?
	function(obj){
		return obj instanceof HTMLElement;
	} :
	function(obj){
		return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
	}
function MakeComp(op={}) {
	let {
		el, // String || dom 必选\
		temp,
		updata, // function 必选
		tagName, // String
		connectedCallback, // 首次被插入 DOM
		disconnectedCallback, // 从 DOM 中删除
		adoptedCallback, // 被移动到新的文档
		// attributeChangedCallback // 增加、删除、修改自身属性时
	 } = op
	this.componentData = {}
	const that = this
	// console.log(tagName);

	tagName = tagName || el
	if (!tagName) {
		console.error('请传入tagName')
		return
	}

	if (typeof el !== 'object'  || !isDOM(el)) {
		if (typeof el === 'string') {
			el = document.getElementById(el)
		} else if (temp) {
			el = document.createElement('template')
			el.innerHTML = temp
		} else {
			console.error('请传入el 或者 temp')
			return
		}
	}
	window.customElements.define('user-' + tagName, class extends HTMLElement {
		constructor() {
		    super();
			const templateElem = el
		    const content = templateElem.content.cloneNode(true);
		    const shadow = this.attachShadow( { mode: 'closed' } );
		    const $ = s => content.querySelector(s)
		    const _updata = updata($, this)

			const _data = new Proxy({}, {
		    	set(obj, prop, value) {
		    		const userFn = _updata[prop]
					if (userFn) {
						userFn(value)
					} else {
						console.log('无效设置属性：' + prop + ',\n updata没有定义相对应的函数')
					}
					obj[prop] = value;
					return true;
		    	}
		    })
			Object.values(this.attributes).forEach(item => {
				_data[item.name] = item.value
			})
		    shadow.appendChild(content);

			this.componentData = _data;
			that.componentData = _data;
			that.el = this;
			connectedCallback = connectedCallback ? connectedCallback.bind(this) : () => {};
			disconnectedCallback = disconnectedCallback ? disconnectedCallback.bind(this) : () => {};
			adoptedCallback = adoptedCallback ? adoptedCallback.bind(this) : () => {};
			// attributeChangedCallback = attributeChangedCallback ? attributeChangedCallback.bind(this) : () => {};
		}
		connectedCallback(e) {
			connectedCallback && connectedCallback(this)
		}
		disconnectedCallback(e) {
			disconnectedCallback && disconnectedCallback(this)
		}
		adoptedCallback(e) {
			adoptedCallback && adoptedCallback(this)
		}
		// 放弃这个api，限制有些大
		// static get observedAttributes () {
	 //        return Object.keys(updata($, this));
	 //        // return ['button'];
	 //    }
		// attributeChangedCallback(e) {
		// 	console.log(e);
		// 	attributeChangedCallback && attributeChangedCallback(this)
		// }

	});
}
